package com.deliveryservicesystem.presentation.desktop;

import com.deliveryservicesystem.app.exceptions.NoRowSelected;
import com.deliveryservicesystem.app.exceptions.OutputError;
import com.deliveryservicesystem.service.impl.GeneralServicesImpl;
import java.awt.event.MouseEvent;
import java.awt.print.PrinterException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.regex.PatternSyntaxException;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

/**
 * File Name: MainPanel.java
 * Version:
 * Description:
 * Package: com.deliveryservicesystem.presentation.desktop
 * Author: Lance
 * Date: Jun 27, 2012
 * Editor:
 */
public class MainPanel extends javax.swing.JPanel
{

    private static final long serialVersionUID = 1L;
    private TableRowSorter<TableModel> rowSorter;
    private GeneralServicesImpl generalServices = new GeneralServicesImpl();
    private TableModel tableModel;
    private String procedureSql;

    /**
     * Creates new form MainPanel
     */
    public MainPanel(String procedureSql) throws SQLException
    {
        initComponents();
        this.procedureSql = procedureSql;
        ResultSet resultSet = generalServices.getTableDataFromProcedure(procedureSql);
        tableModel = GenericTableModel.resultSetToTableModel(resultSet);
        setTableDataFromProcedure(procedureSql);
    }

    private void filterTable(TableRowSorter<TableModel> sorter, String filterText)
    {
        if (!filterText.equals("Enter search value"))
        {
            try
            {
                sorter.setRowFilter(RowFilter.regexFilter(filterText));
            }
            catch (PatternSyntaxException pse)
            {
                JOptionPane.showMessageDialog(this.getParent(), "Bad regex pattern\nPlease filter again", "Bad regex pattern", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    public void setTableDataFromProcedure(String procedureSql) throws SQLException
    {
        ResultSet resultSet = generalServices.getTableDataFromProcedure(procedureSql);
        tableModel = GenericTableModel.resultSetToTableModel(resultSet);
        setTableModel();
    }

    public void setTableDataFromSql(String sql) throws SQLException
    {
        ResultSet resultSet = generalServices.getTableDataFromSql(sql);
        tableModel = GenericTableModel.resultSetToTableModel(resultSet);
        setTableModel();
    }

    private void setTableModel()
    {
        tblMain.setModel(tableModel);
        rowSorter = new TableRowSorter<>(tableModel);
        tblMain.setRowSorter(rowSorter);
    }

    public TableModel getTableModel()
    {
        return tableModel;
    }

    public HashMap<String, String> getSelectedRow() throws NoRowSelected
    {
        int columnCount = tableModel.getColumnCount();
        int selectedRow = tblMain.getSelectedRow();
        HashMap<String, String> values = new HashMap<>();

        try
        {
            if (selectedRow == -1)
            {
                throw new NoRowSelected("Please select a row from the table to edit");
            }
            for (int i = 0; i < columnCount; i++)
            {
                values.put(tableModel.getColumnName(i), tableModel.getValueAt(selectedRow, i).toString());
            }
        }
        catch (NoRowSelected ex)
        {
            throw ex;
        }
        return values;
    }

    public void refreshTable()
    {
        try
        {
            setTableDataFromProcedure(procedureSql);
        }
        catch (SQLException ex)
        {
            OutputError.toLog(ex);
            OutputError.toUser(ex);
        }
    }

    public void printTable() throws PrinterException
    {
        MessageFormat headerFormat = new MessageFormat("Page {0}");
        MessageFormat footerFormat = new MessageFormat("- {0} -");
        tblMain.print(JTable.PrintMode.FIT_WIDTH, headerFormat, footerFormat);
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        popupMenuRightClick = new javax.swing.JPopupMenu();
        menuItemCut = new javax.swing.JMenuItem();
        menuItemCopy = new javax.swing.JMenuItem();
        menuItemPaste = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        menuItemDelete = new javax.swing.JMenuItem();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        tblMain = new javax.swing.JTable();
        btnSearch = new javax.swing.JButton();
        txtSearch = new javax.swing.JTextField();

        menuItemCut.setIcon(new javax.swing.ImageIcon(getClass().getResource("/toolbarButtonGraphics/general/Cut16.gif"))); // NOI18N
        menuItemCut.setText("Cut");
        popupMenuRightClick.add(menuItemCut);

        menuItemCopy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/toolbarButtonGraphics/general/Copy16.gif"))); // NOI18N
        menuItemCopy.setText("Copy");
        popupMenuRightClick.add(menuItemCopy);

        menuItemPaste.setIcon(new javax.swing.ImageIcon(getClass().getResource("/toolbarButtonGraphics/general/Paste16.gif"))); // NOI18N
        menuItemPaste.setText("Paste");
        popupMenuRightClick.add(menuItemPaste);
        popupMenuRightClick.add(jSeparator1);

        menuItemDelete.setIcon(new javax.swing.ImageIcon(getClass().getResource("/toolbarButtonGraphics/general/Delete16.gif"))); // NOI18N
        menuItemDelete.setText("Delete");
        popupMenuRightClick.add(menuItemDelete);

        tblMain.setComponentPopupMenu(popupMenuRightClick);
        tblMain.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                tblMainMouseClicked(evt);
            }
        });
        jScrollPane3.setViewportView(tblMain);

        btnSearch.setIcon(new javax.swing.ImageIcon(getClass().getResource("/toolbarButtonGraphics/general/Find16.gif"))); // NOI18N
        btnSearch.setText("Search");
        btnSearch.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSearchActionPerformed(evt);
            }
        });

        txtSearch.setForeground(new java.awt.Color(204, 204, 204));
        txtSearch.setText("Enter search value");
        txtSearch.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                txtSearchCaretUpdate(evt);
            }
        });
        txtSearch.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                txtSearchFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                txtSearchFocusLost(evt);
            }
        });

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(txtSearch, javax.swing.GroupLayout.PREFERRED_SIZE, 188, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(btnSearch))
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jScrollPane3)))
                .addContainerGap())
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(btnSearch)
                    .addComponent(txtSearch, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPane3)
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    private void btnSearchActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnSearchActionPerformed
    {//GEN-HEADEREND:event_btnSearchActionPerformed
        try
        {
            setTableDataFromProcedure(procedureSql);
        }
        catch (SQLException ex)
        {
            OutputError.toLog(ex);
            OutputError.toUser(ex);
        }
        filterTable(rowSorter, txtSearch.getText().trim());
    }//GEN-LAST:event_btnSearchActionPerformed

    private void txtSearchCaretUpdate(javax.swing.event.CaretEvent evt)//GEN-FIRST:event_txtSearchCaretUpdate
    {//GEN-HEADEREND:event_txtSearchCaretUpdate
        filterTable(rowSorter, txtSearch.getText().trim());
    }//GEN-LAST:event_txtSearchCaretUpdate

    private void txtSearchFocusGained(java.awt.event.FocusEvent evt)//GEN-FIRST:event_txtSearchFocusGained
    {//GEN-HEADEREND:event_txtSearchFocusGained
        if (txtSearch.getText().equals("Enter search value"))
        {
            txtSearch.setText(null);
            txtSearch.setForeground(new java.awt.Color(0, 0, 0));
        }
    }//GEN-LAST:event_txtSearchFocusGained

    private void txtSearchFocusLost(java.awt.event.FocusEvent evt)//GEN-FIRST:event_txtSearchFocusLost
    {//GEN-HEADEREND:event_txtSearchFocusLost
        if (txtSearch.getText().equals(""))
        {
            txtSearch.setText("Enter search value");
            txtSearch.setForeground(new java.awt.Color(204, 204, 204));
        }
    }//GEN-LAST:event_txtSearchFocusLost

    private void tblMainMouseClicked(java.awt.event.MouseEvent evt)//GEN-FIRST:event_tblMainMouseClicked
    {//GEN-HEADEREND:event_tblMainMouseClicked
        if (evt.getButton() == MouseEvent.BUTTON2)
        {
            popupMenuRightClick.show(tblMain, evt.getX(), evt.getY());
        }
    }//GEN-LAST:event_tblMainMouseClicked
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnSearch;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JMenuItem menuItemCopy;
    private javax.swing.JMenuItem menuItemCut;
    private javax.swing.JMenuItem menuItemDelete;
    private javax.swing.JMenuItem menuItemPaste;
    private javax.swing.JPopupMenu popupMenuRightClick;
    private javax.swing.JTable tblMain;
    private javax.swing.JTextField txtSearch;
    // End of variables declaration//GEN-END:variables
}
